"""
A股指数期权自动交易系统主程序
"""
import asyncio
import logging
from contextlib import asynccontextmanager

from fastapi import FastAPI, WebSocket, WebSocketDisconnect
from fastapi.middleware.cors import CORSMiddleware
from fastapi.staticfiles import StaticFiles
from fastapi.responses import HTMLResponse

from app.core.config import settings
from app.core.logger import setup_logging
from app.core.database import db_manager
from app.services.strategy_engine import strategy_engine
from app.services.market_data import market_data_service
from app.services.risk_manager import risk_manager
from app.services.trade_engine import trade_engine
from app.api.routes import router

# 设置日志
setup_logging()
logger = logging.getLogger(__name__)


@asynccontextmanager
async def lifespan(app: FastAPI):
    """应用生命周期管理"""
    # 启动时执行
    logger.info("正在启动A股指数期权自动交易系统...")
    
    try:
        # 初始化数据库
        await db_manager.initialize()
        logger.info("数据库初始化完成")
        
        # 启动各个服务
        await market_data_service.start()
        logger.info("行情服务启动完成")
        
        await strategy_engine.start()
        logger.info("策略引擎启动完成")
        
        await risk_manager.start()
        logger.info("风险管理启动完成")
        
        await trade_engine.start()
        logger.info("交易引擎启动完成")
        
        logger.info("A股指数期权自动交易系统启动完成")
        
    except Exception as e:
        logger.error(f"系统启动失败: {e}")
        raise
    
    yield
    
    # 关闭时执行
    logger.info("正在关闭A股指数期权自动交易系统...")
    
    try:
        # 停止各个服务
        await trade_engine.stop()
        logger.info("交易引擎停止完成")
        
        await risk_manager.stop()
        logger.info("风险管理停止完成")
        
        await strategy_engine.stop()
        logger.info("策略引擎停止完成")
        
        await market_data_service.stop()
        logger.info("行情服务停止完成")
        
        # 关闭数据库连接
        await db_manager.close()
        logger.info("数据库连接关闭完成")
        
        logger.info("A股指数期权自动交易系统已关闭")
        
    except Exception as e:
        logger.error(f"系统关闭失败: {e}")


# 创建FastAPI应用
app = FastAPI(
    title=settings.APP_NAME,
    version=settings.APP_VERSION,
    description="A股指数期权自动交易系统API",
    lifespan=lifespan
)

# 配置CORS
app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

# 注册路由
app.include_router(router)

# WebSocket连接管理
class ConnectionManager:
    def __init__(self):
        self.active_connections: List[WebSocket] = []
    
    async def connect(self, websocket: WebSocket):
        await websocket.accept()
        self.active_connections.append(websocket)
        logger.info(f"WebSocket连接已建立，当前连接数: {len(self.active_connections)}")
    
    def disconnect(self, websocket: WebSocket):
        if websocket in self.active_connections:
            self.active_connections.remove(websocket)
            logger.info(f"WebSocket连接已断开，当前连接数: {len(self.active_connections)}")
    
    async def send_personal_message(self, message: str, websocket: WebSocket):
        try:
            await websocket.send_text(message)
        except Exception as e:
            logger.error(f"发送个人消息失败: {e}")
            self.disconnect(websocket)
    
    async def broadcast(self, message: str):
        disconnected = []
        for connection in self.active_connections:
            try:
                await connection.send_text(message)
            except Exception as e:
                logger.error(f"广播消息失败: {e}")
                disconnected.append(connection)
        
        # 移除断开的连接
        for connection in disconnected:
            self.disconnect(connection)

manager = ConnectionManager()


@app.get("/")
async def root():
    """根路径"""
    return {
        "message": "A股指数期权自动交易系统",
        "version": settings.APP_VERSION,
        "status": "running",
        "timestamp": datetime.now().isoformat()
    }


@app.get("/health")
async def health_check():
    """健康检查"""
    return {
        "status": "healthy",
        "timestamp": datetime.now().isoformat(),
        "services": {
            "strategy_engine": strategy_engine.is_running,
            "market_data": market_data_service.is_running,
            "risk_manager": risk_manager.is_running,
            "trade_engine": trade_engine.is_running
        }
    }


@app.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket):
    """WebSocket端点"""
    await manager.connect(websocket)
    
    try:
        while True:
            # 接收客户端消息
            data = await websocket.receive_text()
            
            # 处理消息
            try:
                import json
                message = json.loads(data)
                
                if message.get("type") == "ping":
                    # 心跳响应
                    await manager.send_personal_message(
                        json.dumps({"type": "pong", "timestamp": datetime.now().isoformat()}),
                        websocket
                    )
                elif message.get("type") == "subscribe":
                    # 订阅特定数据
                    channel = message.get("channel", "all")
                    await manager.send_personal_message(
                        json.dumps({
                            "type": "subscribed",
                            "channel": channel,
                            "timestamp": datetime.now().isoformat()
                        }),
                        websocket
                    )
                
            except json.JSONDecodeError:
                await manager.send_personal_message(
                    json.dumps({"type": "error", "message": "无效的消息格式"}),
                    websocket
                )
            
    except WebSocketDisconnect:
        manager.disconnect(websocket)
    except Exception as e:
        logger.error(f"WebSocket错误: {e}")
        manager.disconnect(websocket)


# 系统状态广播任务
async def broadcast_system_status():
    """广播系统状态"""
    while True:
        try:
            # 构建状态消息
            status_data = {
                "type": "system_status",
                "timestamp": datetime.now().isoformat(),
                "services": {
                    "strategy_engine": strategy_engine.is_running,
                    "market_data": market_data_service.is_running,
                    "risk_manager": risk_manager.is_running,
                    "trade_engine": trade_engine.is_running
                },
                "market_data": {},
                "positions": [],
                "risks": []
            }
            
            # 获取行情数据
            market_data = market_data_service.get_all_market_data()
            for symbol, md in market_data.items():
                status_data["market_data"][symbol] = {
                    "price": md.close,
                    "volume": md.volume,
                    "delta": md.delta,
                    "gamma": md.gamma,
                    "vega": md.vega
                }
            
            # 获取持仓信息
            positions = await db_manager.get_positions()
            status_data["positions"] = positions
            
            # 获取风险状态
            risks = await risk_manager.get_current_risks()
            for risk in risks:
                if risk.exceeded:
                    status_data["risks"].append({
                        "type": risk.limit_type,
                        "message": risk.message
                    })
            
            # 广播消息
            import json
            await manager.broadcast(json.dumps(status_data))
            
        except Exception as e:
            logger.error(f"广播系统状态失败: {e}")
        
        await asyncio.sleep(5)  # 每5秒广播一次


# 启动广播任务
@app.on_event("startup")
async def start_broadcast_task():
    """启动广播任务"""
    asyncio.create_task(broadcast_system_status())


if __name__ == "__main__":
    import uvicorn
    
    logger.info(f"启动服务器: {settings.HOST}:{settings.PORT}")
    
    uvicorn.run(
        "main:app",
        host=settings.HOST,
        port=settings.PORT,
        reload=settings.DEBUG,
        log_level="info"
    )
